package com.forest.oss.impl.ali;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import com.forest.oss.AbstractOssClient;
import com.forest.oss.constants.AclType;
import com.forest.oss.impl.OssProperties;
import org.springframework.util.CollectionUtils;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.List;

public class AliOssClient extends AbstractOssClient {
    private AliOssProperties aliOssProperties;
    private OSS client;

    public AliOssClient(AliOssProperties aliOssProperties) {
        System.out.println("--------------加载阿里对象存储------------");
        this.aliOssProperties=aliOssProperties;
        client = getOssClient();
    }

    private  OSS getOssClient() {
        return new OSSClientBuilder()
                .build(aliOssProperties.getEndPoint(),
                        aliOssProperties.getAppKeyId(),
                        aliOssProperties.getAppSecret());
    }

    @Override
    public OssProperties getProperties() {
        return this.aliOssProperties;
    }

    @Override
    public  String getFolder() {
        return super.getFolder(aliOssProperties.getProject());
    }

    @Override
    public  String upload(String key, String folder, InputStream inputStream, AclType acl) {
        PutObjectRequest request = new PutObjectRequest(aliOssProperties.getBucket(), folder + key, inputStream);
        String contentType = getContentType(key);
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentType(contentType);
        request.setMetadata(metadata);
        client.putObject(request);
        client.setObjectAcl(aliOssProperties.getBucket(), folder + key, CannedAccessControlList.valueOf(acl.name()));
        return folder + key;
    }

    @Override
    public  InputStream download(String key) {
        OSSObject ossObject = client.getObject(aliOssProperties.getBucket(), key);
        InputStream objectContent = ossObject.getObjectContent();
        byte[] content = IoUtil.readBytes(objectContent);
        return new ByteArrayInputStream(content);
    }


    @Override
    public  void delete(String key) {
        client.deleteObject(aliOssProperties.getBucket(), key);
    }

    @Override
    public  List<String> batchDelete(List<String> keys, boolean quiet) {
        Assert.isTrue(CollectionUtils.isEmpty(keys), "删除的文件keys不能为空");
        Assert.isTrue(keys.size() > 1000, "删除的文件keys超过了最大限制1000个");
        DeleteObjectsRequest request = new DeleteObjectsRequest(aliOssProperties.getBucket()).withKeys(keys).withQuiet(quiet);
        DeleteObjectsResult result = client.deleteObjects(request);
        List<String> data = result.getDeletedObjects();
        return data;
    }

    @Override
    public String getFile(String key, AclType acl) {
        if(StrUtil.equalsIgnoreCase(CannedAccessControlList.PublicRead.name(), acl.name())) {
            return buildPublicUrl(aliOssProperties.getBucketDomain(), key);
        } else {
            DateTime date = DateUtil.offsetDay(DateUtil.date(), 7);
            String url = client.generatePresignedUrl(aliOssProperties.getBucket(), key, date).getPath();
            return url;
        }
    }

    @Override
    public Boolean exists(String key) {
        GenericRequest request = new GenericRequest(aliOssProperties.getBucket(), key);
        return client.doesObjectExist(request);
    }
}
